package com.example.sixteen.jt;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.sixteen.jt.adapter.EpcBean;
import com.example.sixteen.jt.adapter.ListViewAdapter;
import com.example.sixteen.jt.databinding.ActivityMainBinding;
import com.example.sixteen.jt.lib.JTAnt;
import com.example.sixteen.jt.lib.JTFreq;
import com.example.sixteen.jt.lib.Reader;
import com.example.sixteen.jt.lib.SelMark;
import com.example.sixteen.jt.utils.PreferenceUtils;
import com.example.sixteen.jt.utils.StringUtils;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;
    private static final String TAG = "XXX_MAIN";

    private Reader reader;
    private List<String> indexes = new ArrayList<>();
    private List<EpcBean> epcBeanList = new ArrayList<>();
    private ListViewAdapter listViewAdapter;

    private PreferenceUtils preferenceUtils;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        reader = new Reader();
        Map<Integer, Integer> antBoxMap = new HashMap<>();
        for (int i = 0; i < 16; i++) {
            antBoxMap.put(i + 1, i + 1);
        }
        reader.setMapAntennaBox(antBoxMap);
        reader.setOnReaderListener(listener);

        preferenceUtils = PreferenceUtils.getInstance();
        preferenceUtils.init(this);

        listViewAdapter = new ListViewAdapter(this);
        binding.listViewEpc.setAdapter(listViewAdapter);
        binding.buttonConnect.setOnClickListener(onClickListener);
        binding.buttonDisconnect.setOnClickListener(onClickListener);
        binding.buttonInventory.setOnClickListener(onClickListener);
        binding.buttonGetAnt.setOnClickListener(onClickListener);
        binding.buttonSetAnt.setOnClickListener(onClickListener);
        binding.buttonLightMulti.setOnClickListener(onClickListener);
        binding.buttonStopMulti.setOnClickListener(onClickListener);
        binding.textAll.setOnClickListener(viewClickListener);
        binding.textCount1.setOnClickListener(viewClickListener);
        binding.textCount2.setOnClickListener(viewClickListener);
        binding.textCount3.setOnClickListener(viewClickListener);
        binding.textCount4.setOnClickListener(viewClickListener);
        binding.textCount5.setOnClickListener(viewClickListener);
        binding.textCount6.setOnClickListener(viewClickListener);
        binding.textCount7.setOnClickListener(viewClickListener);
        binding.textCount8.setOnClickListener(viewClickListener);
        binding.textCount9.setOnClickListener(viewClickListener);
        binding.textCount10.setOnClickListener(viewClickListener);
        binding.textCount11.setOnClickListener(viewClickListener);
        binding.textCount12.setOnClickListener(viewClickListener);
        binding.textCount13.setOnClickListener(viewClickListener);
        binding.textCount14.setOnClickListener(viewClickListener);
        binding.textCount15.setOnClickListener(viewClickListener);
        binding.textCount16.setOnClickListener(viewClickListener);
        binding.buttonSetFreq.setOnClickListener(onClickListener);
        binding.buttonGetFreq.setOnClickListener(onClickListener);
        binding.buttonSetBox.setOnClickListener(onClickListener);

        binding.listViewEpc.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                EpcBean bean = (EpcBean) listViewAdapter.getItem(i);
                if (bean.isSelected()) {
                    listViewAdapter.deselect(i);
                } else {
                    listViewAdapter.select(i);
                }
            }
        });

        binding.editTimes.setText(preferenceUtils.getTimes() + "");
        binding.editIp.setText(preferenceUtils.getIp());
    }

    private View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.button_connect:
                    String ip = binding.editIp.getText().toString();
                    if (reader.connect(ip, 20058) == Reader.SUCCESS) {
                        preferenceUtils.setIp(ip);
                        binding.buttonDisconnect.setEnabled(true);
                        binding.buttonConnect.setEnabled(false);
                        binding.buttonInventory.setEnabled(true);
                        binding.buttonGetAnt.setEnabled(true);
                        binding.buttonSetAnt.setEnabled(true);
                        binding.buttonLightMulti.setEnabled(true);
                        binding.buttonStopMulti.setEnabled(true);
                        binding.buttonGetFreq.setEnabled(true);
                        binding.buttonSetFreq.setEnabled(true);
                        showToast("CONNECT_SUCCESS");
                    } else {
                        showToast("CONNECT_FAIL");
                    }
                    break;
                case R.id.button_disconnect:
                    if (reader.disconnect() == Reader.SUCCESS) {
                        showToast("DISCONNECT_SUCCESS");
                        binding.buttonConnect.setEnabled(true);
                        binding.buttonDisconnect.setEnabled(false);
                        binding.buttonInventory.setEnabled(false);
                        binding.buttonGetAnt.setEnabled(false);
                        binding.buttonSetAnt.setEnabled(false);
                        binding.buttonLightMulti.setEnabled(false);
                        binding.buttonStopMulti.setEnabled(false);
                        binding.buttonSetFreq.setEnabled(false);
                        binding.buttonGetFreq.setEnabled(false);
                        listViewAdapter.deselect();
                    } else {
                        showToast("DISCONNECT_FAIL");
                    }
                    break;
                case R.id.button_inventory:
                    int times = Integer.parseInt(binding.editTimes.getText().toString());
                    indexes.clear();
                    epcBeanList.clear();
                    listViewAdapter.setData(null);
                    binding.buttonInventory.setEnabled(false);
                    binding.buttonGetAnt.setEnabled(false);
                    binding.buttonSetAnt.setEnabled(false);
                    binding.buttonLightMulti.setEnabled(false);
                    binding.buttonStopMulti.setEnabled(false);
                    binding.buttonSetFreq.setEnabled(false);
                    binding.buttonGetFreq.setEnabled(false);
                    reader.inventory(times);
                    preferenceUtils.setTimes(times);
                    break;
                case R.id.button_get_ant:
                    JTAnt[] ants1 = new JTAnt[16];
                    if (reader.getAnt(ants1) == Reader.SUCCESS) {
                        for (int i = 0; i < ants1.length; i++) {
                            CheckBox chk = binding.layoutAnt.findViewWithTag(String.format("ant%d", i + 1));
                            chk.setChecked(ants1[i].getEnabled() == 1);
                            if (chk.isChecked()) {
                                binding.editPower.setText(String.valueOf(ants1[i].getPower()));
                                binding.editSingle.setText(String.valueOf(ants1[i].getWork()));
                                binding.editSleep.setText(String.valueOf(ants1[i].getSleep()));
                            }
                        }
                        showToast("GET_SUCCESS");
                    } else {
                        showToast("GET_FAIL");
                    }
                    break;
                case R.id.button_set_ant:
                    JTAnt[] ants2 = new JTAnt[16];
                    int power = Integer.parseInt(binding.editPower.getText().toString());
                    int work = Integer.parseInt(binding.editSingle.getText().toString());
                    int sleep = Integer.parseInt(binding.editSleep.getText().toString());
                    for (int i = 0; i < 16; i++) {
                        JTAnt ant = new JTAnt();
                        CheckBox chk = binding.layoutAnt.findViewWithTag(String.format("ant%d", i + 1));
                        ant.setEnabled(chk.isChecked() ? 1 : 0);
                        ant.setPower(power);
                        ant.setWork(work);
                        ant.setSleep(sleep);
                        ants2[i] = ant;
                    }
                    if (reader.setAnt(ants2) == Reader.SUCCESS) {
                        showToast("SET_SUCCESS");
                    } else {
                        showToast("SET_FAIL");
                    }
                    break;
                case R.id.button_light_multi:
                    List<EpcBean> selected = listViewAdapter.getSelected();
                    List<SelMark> marks = new ArrayList<>();
                    for (EpcBean bean : selected) {
                        SelMark item = new SelMark();
                        item.setAnt(bean.getAnt());
                        byte[] epc = StringUtils.hex2Bytes(bean.getEpc());
                        item.setMark(epc);
                        item.setLen(epc.length);
                        marks.add(item);
                    }
                    reader.startLightMulti(marks.toArray(new SelMark[marks.size()]), Integer.parseInt(binding.editLightTimes.getText().toString()));
                    binding.buttonStopMulti.setEnabled(true);
                    binding.buttonInventory.setEnabled(false);
                    binding.buttonLightMulti.setEnabled(false);
                    binding.buttonSetFreq.setEnabled(false);
                    binding.buttonGetFreq.setEnabled(false);
                    break;
                case R.id.button_stop_multi:
                    reader.stopLightMulti();
                    binding.buttonInventory.setEnabled(true);
                    binding.buttonGetAnt.setEnabled(true);
                    binding.buttonSetAnt.setEnabled(true);
                    binding.buttonLightMulti.setEnabled(true);
                    binding.buttonStopMulti.setEnabled(true);
                    binding.buttonSetFreq.setEnabled(true);
                    binding.buttonGetFreq.setEnabled(true);
                    listViewAdapter.deselect();
                    break;
                case R.id.button_set_freq:
                    JTFreq freqSet = new JTFreq();
                    freqSet.setStatus(0);
                    freqSet.setRegion(1);
                    freqSet.setMHz(915);
                    freqSet.setKHz(250);
                    freqSet.setStep(500);
                    freqSet.setChannels(26);
                    if (reader.setFreq(freqSet) == Reader.SUCCESS) {
                        showToast("SET_SUCCESS");
                    } else {
                        showToast("SET_FAIL");
                    }
                    break;
                case R.id.button_get_freq:
                    JTFreq freqGet = new JTFreq();
                    if (reader.getFreq(freqGet) == Reader.SUCCESS) {
                        showToast(freqGet.toString());
                    } else {
                        showToast("GET_FAIL");
                    }
                    break;
                case R.id.button_set_box:
                    break;
                default:
                    break;
            }
        }
    };

    private View.OnClickListener viewClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            int tag = Integer.parseInt(view.getTag().toString());
            if (tag == 0) {
                listViewAdapter.setData(epcBeanList);
            } else {
                listViewAdapter.setData(epcBeanList.stream().filter(x -> x.getBox() == tag).collect(Collectors.toList()));
            }
        }
    };

    private Reader.OnReaderListener listener = new Reader.OnReaderListener() {
        @Override
        public void onAlive(String ip) {

        }

        @Override
        public void onInventory(String ip, String epc, int ant, int box, int rssi, boolean high) {
            int idx = indexes.indexOf(epc);
            if (idx == -1) {
                indexes.add(epc);
                EpcBean bean = new EpcBean();
                bean.setEpc(epc);
                bean.setCount(1);
                bean.setAnt(ant);
                bean.setBox(box);
                bean.setRssi(rssi);
                epcBeanList.add(bean);
                int[] antCounts = new int[16];
                antCounts[ant - 1] = 1;
                bean.setAntCounts(antCounts);
                bean.setHigh(high);
            } else {
                EpcBean bean = epcBeanList.get(idx);
                if (bean.isHigh() == high) {
                    bean.setCount(bean.getCount() + 1);
                    bean.getAntCounts()[ant - 1] += 1;
                    if (bean.getRssi() < rssi) {
                        bean.setRssi(rssi);
                        bean.setAnt(ant);
                        bean.setBox(box);
                    }
                }
            }
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    listViewAdapter.setData(epcBeanList);
                }
            });
        }

        @Override
        public void onStop(String ip) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    binding.buttonInventory.setEnabled(true);
                    binding.buttonGetAnt.setEnabled(true);
                    binding.buttonSetAnt.setEnabled(true);
                    binding.buttonLightMulti.setEnabled(true);
                    binding.buttonStopMulti.setEnabled(true);
                    binding.buttonGetFreq.setEnabled(true);
                    binding.buttonSetFreq.setEnabled(true);
                    epcBeanList.sort(new Comparator<EpcBean>() {
                        @Override
                        public int compare(EpcBean epcBean, EpcBean t1) {
                            return epcBean.getEpc().compareTo(t1.getEpc());
                        }
                    });
                    listViewAdapter.setData(epcBeanList);
                    Toast.makeText(MainActivity.this, epcBeanList.size() + "", Toast.LENGTH_SHORT).show();

                    for (EpcBean bean : epcBeanList) {
                        Log.d(TAG, bean.getEpc() + "," + bean.getRssi() + Arrays.stream(bean.getAntCounts()).mapToObj(String::valueOf).collect(Collectors.toList()));
                    }

                    binding.textAll.setText(String.format("ALL:%1d", epcBeanList.size()));
                    binding.textCount1.setText(String.format("#1:%1d", epcBeanList.stream().filter(x -> x.getBox() == 1).count()));
                    binding.textCount2.setText(String.format("#2:%1d", epcBeanList.stream().filter(x -> x.getBox() == 2).count()));
                    binding.textCount3.setText(String.format("#3:%1d", epcBeanList.stream().filter(x -> x.getBox() == 3).count()));
                    binding.textCount4.setText(String.format("#4:%1d", epcBeanList.stream().filter(x -> x.getBox() == 4).count()));
                    binding.textCount5.setText(String.format("#5:%1d", epcBeanList.stream().filter(x -> x.getBox() == 5).count()));
                    binding.textCount6.setText(String.format("#6:%1d", epcBeanList.stream().filter(x -> x.getBox() == 6).count()));
                    binding.textCount7.setText(String.format("#7:%1d", epcBeanList.stream().filter(x -> x.getBox() == 7).count()));
                    binding.textCount8.setText(String.format("#8:%1d", epcBeanList.stream().filter(x -> x.getBox() == 8).count()));
                    binding.textCount9.setText(String.format("#9:%1d", epcBeanList.stream().filter(x -> x.getBox() == 9).count()));
                    binding.textCount10.setText(String.format("#10:%1d", epcBeanList.stream().filter(x -> x.getBox() == 10).count()));
                    binding.textCount11.setText(String.format("#11:%1d", epcBeanList.stream().filter(x -> x.getBox() == 11).count()));
                    binding.textCount12.setText(String.format("#12:%1d", epcBeanList.stream().filter(x -> x.getBox() == 12).count()));
                    binding.textCount13.setText(String.format("#13:%1d", epcBeanList.stream().filter(x -> x.getBox() == 13).count()));
                    binding.textCount14.setText(String.format("#14:%1d", epcBeanList.stream().filter(x -> x.getBox() == 14).count()));
                    binding.textCount15.setText(String.format("#15:%1d", epcBeanList.stream().filter(x -> x.getBox() == 15).count()));
                    binding.textCount16.setText(String.format("#16:%1d", epcBeanList.stream().filter(x -> x.getBox() == 16).count()));
                }
            });
        }
    };

    private void showToast(String message) {
        Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
    }
}